package cn.xzzz2020.XJynWeb.mvc;

import cn.xzzz2020.XJynWeb.mvc.processor.RequestProcessor;
import cn.xzzz2020.XJynWeb.mvc.render.ResultRender;
import cn.xzzz2020.XJynWeb.mvc.render.impl.DefaultResultRender;
import cn.xzzz2020.XJynWeb.mvc.render.impl.InternalErrorResultRender;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Iterator;

/**
 * 责任链处理实例
 * 1.以责任链的模式执行注册的请求处理器
 * 2.委派给特定的Render实例对处理的结果进行渲染
 *
 * @author xzzz2020
 * @version 1.0
 * @date 2020/9/4 16:05
 */
@Slf4j
public class RequestProcessorChain {

    //请求处理器迭代器
    private final Iterator<RequestProcessor> requestProcessorIterator;
    //请求Request
    private final HttpServletRequest request;
    //请求Response
    private final HttpServletResponse response;
    //http请求方法
    private String requestMethod;
    //http请求路径
    private String requestPath;
    //请求状态码
    private int responseCode;
    //请求结果渲染器
    private ResultRender resultRender;

    public RequestProcessorChain(Iterator<RequestProcessor> requestProcessorIterator, HttpServletRequest req, HttpServletResponse resp) {
        this.requestProcessorIterator = requestProcessorIterator;
        this.request = req;
        this.response = resp;
        this.requestMethod = req.getMethod();
        this.requestPath = req.getPathInfo();
        this.responseCode = HttpServletResponse.SC_OK;
    }

    /**
     * 以责任链的模式处理请求
     */
    public void doRequestProcessorChain() {
        //1.通过迭代器遍历注册的请求处理器实现类列表
        try {
            while (requestProcessorIterator.hasNext()) {
                //2.直到某个请求处理器执行后返回为false为止
                RequestProcessor requestProcessor = requestProcessorIterator.next();
                boolean processStatue = requestProcessor.process(this);
                if (!processStatue) {
                    break;
                }
            }
        } catch (Exception e) {
            //3.期间如果出现异常，则交由内部异常渲染器处理
            this.resultRender = new InternalErrorResultRender(e.getMessage());
            log.error("doRequestProcessorChain error:", e);
        }

    }

    /**
     * 结果渲染器
     */
    public void doRender() {
        //1.如果请求处理器实现类均未选择合适的渲染器，则使用默认的
        if (this.resultRender == null) {
            this.resultRender = new DefaultResultRender();
        }
        try {
            //2.调用渲染器的render方法对结果进行渲染
            resultRender.render(this);
        } catch (Exception e) {
            log.error("doRender error:", e);
            throw new RuntimeException(e);
        }
    }

    public Iterator<RequestProcessor> getRequestProcessorIterator() {
        return requestProcessorIterator;
    }

    public HttpServletRequest getRequest() {
        return request;
    }

    public HttpServletResponse getResponse() {
        return response;
    }

    public String getRequestMethod() {
        return requestMethod;
    }

    public void setRequestMethod(String requestMethod) {
        this.requestMethod = requestMethod;
    }

    public String getRequestPath() {
        return requestPath;
    }

    public void setRequestPath(String requestPath) {
        this.requestPath = requestPath;
    }

    public int getResponseCode() {
        return responseCode;
    }

    public void setResponseCode(int responseCode) {
        this.responseCode = responseCode;
    }

    public ResultRender getResultRender() {
        return resultRender;
    }

    public void setResultRender(ResultRender resultRender) {
        this.resultRender = resultRender;
    }
}
